package com.gitee.wsl.doc.prosemirror.model.fragment.ext

import com.gitee.wsl.doc.prosemirror.model.content.ResolvedPos
import com.gitee.wsl.doc.prosemirror.model.fragment.Fragment
import com.gitee.wsl.doc.prosemirror.model.node.Node
import com.gitee.wsl.doc.prosemirror.model.node.NodeType
import com.gitee.wsl.doc.prosemirror.model.node.ext.withWrappers


// Takes a slice parsed with parseSlice, which means there hasn't been
// any content-expression checking done on the top nodes, tries to
// find a parent node in the current context that might fit the nodes,
// and if successful, rebuilds the slice so that it fits into that parent.
//
// This addresses the problem that Transform.replace expects a
// coherent slice, and will fail to place a set of siblings that don't
// fit anywhere in the schema.
fun normalizeSiblings(fragment: Fragment, context: ResolvedPos): Fragment{
//    if (fragment.childCount < 2) return fragment
//    (context.depth .. 0).forEach { d ->
//        val parent = context.node(d)
//        val match = parent.contentMatchAt(context.index(d))
//        val lastWrap: List<NodeType>
//        val result: List<Node>? = null
//        fragment.forEach { node, offset, index ->
//            if (result == null) {
//                return@forEach
//                val wrap = match.findWrapping(node.type)
//                val inLast:NodeType
//
//
//            } else {
//
//            }
//        }
//    }

//    for (let d = context.depth; d >= 0; d--) {
//        let parent = context.node(d)
//        let match = parent.contentMatchAt(context.index(d))
//        let lastWrap: readonly NodeType[] | undefined, result: Node[] | null = []
//        fragment.forEach(node => {
//            if (!result) return
//            let wrap = match.findWrapping(node.type), inLast
//            if (!wrap) return result = null
//            if (inLast = result.length && lastWrap!.length && addToSibling(wrap, lastWrap!, node, result[result.length - 1], 0)) {
//            result[result.length - 1] = inLast
//        } else {
//            if (result.length) result[result.length - 1] = closeRight(result[result.length - 1], lastWrap!.length)
//            let wrapped = withWrappers(node, wrap)
//            result.push(wrapped)
//            match = match.matchType(wrapped.type)!
//            lastWrap = wrap
//        }
//        })
//        if (result) return Fragment.from(result)
//    }
    return fragment
}

// Used to group adjacent nodes wrapped in similar parents by
// normalizeSiblings into the same parent node
fun addToSibling(wrap: List<NodeType>, lastWrap: List<NodeType>, node: Node, sibling: Node, depth: Int): Node? {
    if (depth < wrap.size && depth < lastWrap.size && wrap[depth] == lastWrap[depth]) {
        val inner = addToSibling(wrap, lastWrap, node, sibling.lastChild!!, depth + 1)
        if (inner!=null) return sibling.copy(sibling.content.replaceChild(sibling.childCount - 1, inner))
        val match = sibling.contentMatchAt(sibling.childCount)
        val type = if(depth == wrap.size - 1) node.type else  wrap[depth + 1]
        if (match.matchType(type)!=null)
           return sibling.copy(sibling.content.append(Fragment.from(node.withWrappers( wrap, depth + 1))))
    }
    return null
}